import type { TableType } from '#/views/onlineDesign/designPage/template/table/type/TableType';

import { querySelectTableApi, querySelectTreeTableApi } from '#/api';
import { queryDictOptionsApi } from '#/utils';

// 输入的组件类型参数[也就是模型中的原组件类型]
export type InputComponentType =
  | 'ApiRadioGroup'
  | 'ApiSelect'
  | 'ApiTreeSelect'
  | 'DatePicker'
  | 'DateTimePicker'
  | 'Input'
  | 'InputNumber'
  | 'InputPassword'
  | 'SparkEditor'
  | 'SparkUploadFile'
  | 'SparkUploadImg'
  | 'Textarea'
  | 'TimePicker';
// 实际需要生成的组件类型[可能会包含不存在的类型,生成一致性的组件]
export type ActualComponentType =
  | 'ApiRadioGroupDict'
  | 'ApiRadioGroupTable'
  | 'ApiSelectDict'
  | 'ApiSelectTable'
  | 'ApiTreeSelect'
  | 'DatePicker'
  | 'Input'
  | 'InputNumber'
  | 'InputPassword'
  | 'SparkUpload'
  | 'SparkUploadFile'
  | 'TimePicker';

/**
 * 将下划线分隔的字符串转换为驼峰命名
 * @param str 下划线分隔的字符串
 * @returns 驼峰命名的字符串
 */
export function toCamelCase(str: string): string {
  return str.replaceAll(/([-_][a-z])/gi, ($1) => {
    return $1.toUpperCase().replace('-', '').replace('_', '');
  });
}

/**
 * 对数据进行排序
 * @param data
 */
export async function sort(data: Array) {
  // 对数组进行排序，基于 sequence 属性升序排序
  data.sort((a, b) => a.extra.sequence - b.extra.sequence);
}

/**
 * 对数据进行排序
 * @param data
 */
export async function sortSeq(data: Array) {
  // 对数组进行排序，基于 sequence 属性升序排序
  data.sort((a, b) => a.sequence - b.sequence);
}

// 实际生成的组件的
function getComponentOption(componentType: ActualComponentType, params: any) {
  // 只处理特殊类型的组件,其余统一处理
  switch (componentType) {
    // 单选框(字典下拉)
    case 'ApiRadioGroupDict': {
      return {
        ...params.commonProps,
        component: 'ApiRadioGroup',
        componentProps: {
          ...params.componentProps,
          afterFetch: (data) =>
            data.map(({ itemText, itemVal }) => ({
              label: itemText,
              value: params.dataType ? Number.parseInt(itemVal) : itemVal,
            })),
          api: queryDictOptionsApi,
          params: { dictCode: params.dictCode },
        },
      } as TableType.FormComponent;
    }
    // 单选框(表下拉)
    case 'ApiRadioGroupTable': {
      return {
        ...params.commonProps,
        component: 'ApiRadioGroup',
        componentProps: {
          ...params.componentProps,
          api: querySelectTableApi,
          params: {
            tableName: params.tableName,
            labelField: params.labelField,
            valueField: params.valueField,
            sqlSelect: 'del_flag = 0',
          },
        },
      } as TableType.FormComponent;
    }
    // 下拉框(字典下拉)
    case 'ApiSelectDict': {
      return {
        ...params.commonProps,
        component: 'ApiSelect',
        componentProps: {
          ...params.componentProps,
          afterFetch: (data) =>
            data.map(({ itemText, itemVal }) => ({
              label: itemText,
              value: params.dataType ? Number.parseInt(itemVal) : itemVal,
            })),
          api: queryDictOptionsApi,
          params: { dictCode: params.dictCode },
        },
      } as TableType.FormComponent;
    }
    // 下拉框(表下拉)
    case 'ApiSelectTable': {
      return {
        ...params.commonProps,
        component: 'ApiSelect',
        componentProps: {
          ...params.componentProps,
          api: querySelectTableApi,
          params: {
            tableName: params.tableName,
            labelField: params.labelField,
            valueField: params.valueField,
            sqlSelect: 'del_flag = 0',
          },
        },
      } as TableType.FormComponent;
    }
    case 'ApiTreeSelect': {
      return {
        ...params.commonProps,
        component: `${componentType}`,
        componentProps: {
          ...params.componentProps,
        },
      } as TableType.FormComponent;
    }
    case 'DatePicker': {
      return {
        ...params.commonProps,
        component: 'DatePicker',
        componentProps: {
          ...params.componentProps,
        },
      };
    }
    case 'Input': {
      return {
        ...params.commonProps,
        component: `${componentType}`,
        componentProps: {
          placeholder: `请输入${params.placeholder}`,
        },
      } as TableType.FormComponent;
    }
    case 'SparkUpload': {
      return params.componentProps
        ? ({
            ...params.commonProps,
            componentProps: {
              ...params.componentProps,
            },
            component: `${componentType}`,
          } as TableType.FormComponent)
        : ({
            ...params.commonProps,
            component: `${componentType}`,
          } as TableType.FormComponent);
    }
    case 'SparkUploadFile': {
      return {
        ...params.commonProps,
        component: `${componentType}`,
        componentProps: {
          ...params.componentProps,
        },
      } as TableType.FormComponent;
    }
    case 'TimePicker': {
      return {
        ...params.commonProps,
        component: 'TimePicker',
        componentProps: {
          ...params.componentProps,
        },
      };
    }
    default: {
      return {
        ...params.commonProps,
        component: `${componentType}`,
        componentProps: {
          placeholder: `请输入${params.placeholder}`,
        },
      } as TableType.FormComponent;
    }
  }
}

// 通用的表单组件处理方法
export const commonMethod = {
  /**
   * 获取组件类型
   * @param field 字段类型
   * @param commonProps 组件参数
   * @param select 是否查询表单
   * @param config 配置JSON
   */
  getComponent: (
    field: object,
    commonProps: TableType.FormComponent,
    select: boolean = false,
    config: any,
  ) => {
    const componentType: InputComponentType = field.componentName;
    // 只处理特殊类型的组件,其余统一处理
    switch (componentType) {
      case 'ApiRadioGroup': {
        // （关联（0否 1是））
        if (field.fieldRelevance === 1) {
          // 是字典下拉还是表下拉
          const apiProps = select
            ? {
                allowClear: true,
                showSearch: true,
                placeholder: `请选择${field.fieldAnnotation}`,
              }
            : {
                buttonStyle: 'solid',
                optionType: 'button',
              };
          // 关联模式（0关联模型 1关联字典）
          if (field.fieldRelevanceMode === 1) {
            if (select) {
              config.selectForm.extra.existDict = true;
              return getComponentOption('ApiSelectDict', {
                commonProps,
                componentProps: apiProps,
                // 数据类型转换
                dataType: field.fieldPackagePath.includes('Integer'),
                dictCode: field.fieldRelevanceModeValKey,
              });
            } else {
              config.form.extra.existDict = true;
            }
            return getComponentOption('ApiRadioGroupDict', {
              commonProps,
              componentProps: apiProps,
              // 数据类型转换
              dataType: field.fieldPackagePath.includes('Integer'),
              dictCode: field.fieldRelevanceModeValKey,
            });
          } else if (field.fieldRelevanceMode === 0) {
            if (select) {
              config.selectForm.extra.existTable = true;
              return getComponentOption('ApiSelectTable', {
                commonProps,
                componentProps: apiProps,
                tableName: field.fieldRelevanceModeModelCode,
                labelField: field.fieldRelevanceModeValKey,
                valueField: field.fieldRelevanceModeModelField,
              });
            } else {
              config.form.extra.existTable = true;
            }
            return getComponentOption('ApiRadioGroupTable', {
              commonProps,
              componentProps: apiProps,
              tableName: field.fieldRelevanceModeModelCode,
              labelField: field.fieldRelevanceModeValKey,
              valueField: field.fieldRelevanceModeModelField,
            });
          }
        }
        return getComponentOption('Input', {
          commonProps,
          placeholder: field.fieldAnnotation,
        });
      }
      case 'ApiSelect': {
        // （关联（0否 1是））
        if (field.fieldRelevance === 1) {
          // 是字典下拉还是表下拉
          const apiProps = {
            allowClear: true,
            showSearch: true,
            placeholder: `请选择${field.fieldAnnotation}`,
          };
          // 关联模式（0关联模型 1关联字典 2关联树模型）
          if (field.fieldRelevanceMode === 1) {
            if (select) {
              config.selectForm.extra.existDict = true;
            } else {
              config.form.extra.existDict = true;
            }
            return getComponentOption('ApiSelectDict', {
              commonProps,
              componentProps: apiProps,
              // 数据类型转换
              dataType: field.fieldPackagePath.includes('Integer'),
              dictCode: field.fieldRelevanceModeValKey,
            });
          } else if (field.fieldRelevanceMode === 0) {
            if (select) {
              config.selectForm.extra.existTable = true;
            } else {
              config.form.extra.existTable = true;
            }
            return getComponentOption('ApiSelectTable', {
              commonProps,
              componentProps: apiProps,
              tableName: field.fieldRelevanceModeModelCode,
              labelField: field.fieldRelevanceModeValKey,
              valueField: field.fieldRelevanceModeModelField,
            });
          }
        }
        return getComponentOption('Input', {
          commonProps,
          placeholder: field.fieldAnnotation,
        });
      }
      case 'ApiTreeSelect': {
        // （关联（0否 1是）） 关联模式（0关联模型 1关联字典 2关联树模型）
        if (field.fieldRelevance === 1 && field.fieldRelevanceMode === 2) {
          if (select) {
            config.selectForm.extra.existTreeTable = true;
          } else {
            config.form.extra.existTreeTable = true;
          }
          const apiProps = {
            api: () =>
              querySelectTreeTableApi({
                tableName: field.fieldRelevanceModeModelCode,
                labelField: field.fieldRelevanceModeValKey,
                valueField: field.fieldRelevanceModeModelField,
                sqlSelect: 'del_flag = 0',
              }),
            labelField: 'name',
            childrenField: 'children',
            valueField: 'id',
            placeholder: `请选择${field.fieldAnnotation}`,
          };
          // 设置额外参数
          commonProps.extra = {
            ...commonProps.extra,
            params: {
              tableName: field.fieldRelevanceModeModelCode,
              labelField: field.fieldRelevanceModeValKey,
              valueField: field.fieldRelevanceModeModelField,
              sqlSelect: 'del_flag = 0',
            },
          };
          return getComponentOption('ApiTreeSelect', {
            commonProps,
            componentProps: apiProps,
          });
        }
        return getComponentOption('Input', {
          commonProps,
          placeholder: field.fieldAnnotation,
        });
      }
      case 'DatePicker': {
        const componentProps = {
          allowClear: true,
          format: 'YYYY-MM-DD',
          valueFormat: 'YYYY-MM-DD',
          placeholder: `请选择${field.fieldAnnotation}`,
        };
        return getComponentOption('DatePicker', {
          commonProps,
          componentProps,
        });
      }
      case 'DateTimePicker': {
        const componentProps = {
          allowClear: true,
          showTime: true,
          format: 'YYYY-MM-DD HH:mm:ss',
          valueFormat: 'YYYY-MM-DD HH:mm:ss',
          placeholder: `请选择${field.fieldAnnotation}`,
        };
        return getComponentOption('DatePicker', {
          commonProps,
          componentProps,
        });
      }
      case 'SparkUploadFile': {
        return getComponentOption('SparkUpload', {
          commonProps,
          componentProps: {
            listType: 'text',
          },
        });
      }
      case 'SparkUploadImg': {
        return getComponentOption('SparkUpload', { commonProps });
      }
      case 'Textarea': {
        return select
          ? getComponentOption('Input', {
              commonProps,
              placeholder: field.fieldAnnotation,
            })
          : getComponentOption(componentType, {
              commonProps,
              placeholder: field.fieldAnnotation,
            });
      }
      case 'TimePicker': {
        const componentProps = {
          allowClear: true,
          format: 'HH:mm:ss',
          valueFormat: 'HH:mm:ss',
          placeholder: `请选择${field.fieldAnnotation}`,
        };
        return getComponentOption('TimePicker', {
          commonProps,
          componentProps,
        });
      }
      default: {
        return getComponentOption(componentType, {
          commonProps,
          placeholder: field.fieldAnnotation,
        });
      }
    }
  },
};

/**
 * 实现校验代码
 * @param field 字段信息
 * @return 这里不会生成复杂的校验信息，只会生成简单的校验必填
 */
export function isRules(field) {
  if (field.fieldRule === 0) {
    return undefined;
  }
  // 非空校验（0否 1是）
  const notNullRule = field.fieldRuleNotNull === 1;
  if (notNullRule) {
    return 'required';
  }
  return undefined;
}
